//xss_clean.js
/*
This is a port of a function called xss_clean in the PHP framework called CodeIgniter version 1.4.1 ( http://codeigniter.com/) to javascript
All comments in this function is from the original source.
Ported by: slamidtfyn
More info at: www.soerenlarsen.dk/development-projects/xss-clean

History:
2007-09-19 Version 1: First release
2007-09-20 Version 2: Moved javascript code to js file
2007-09-24 Version 3: Error in html_entity_decode fixed
2007-09-24 Version 4: Major error in xss_clean function fixed (http://micropledge.com/projects/convert-php-xss-clean-function-to-javascript/comments#c126)
*/
function xss_clean(str)
{    
	// Remove Null Characters
	// This prevents sandwiching null characters
	//
	// between ascii characters, like Java\0script.
	str=str.replace(/\\0/gi, '')
	str=str.replace(/\\\\0/gi, '')
	
	/*
		* Validate standard character entites
		*
		* Add a semicolon if missing.  We do this to enable
		* the conversion of entities to ASCII later.
		*
		*/
	str = str.replace(/#(&\#*\w+)[\x00-\x20]+;#u/g,"$1;")
	/*
		* Validate UTF16 two byte encodeing (x00) 
		*
		* Just as above, adds a semicolon if missing.
		*
		*/
	str = str.replace(/#(&\#x*)([0-9A-F]+);*#iu/g,"$1$2;")
	
	/*
		* URL Decode
		*
		* Just in case stuff like this is submitted:
		*
		* <a href="http://%77%77%77%2E%67%6F%6F%67%6C%65%2E%63%6F%6D">Google</a>
		*
		* Note: Normally urldecode() would be easier but it removes plus signs
		*
		*/    	
	str = str.replace(/%u0([a-z0-9]{3})/gi, "&#x$1;")
	str = str.replace(/%([a-z0-9]{2})/gi, "&#x$1;")   
	/*I'll \"walk\" the <b>dog</b> now*/
	/*
		* Convert character entities to ASCII 
		*
		* This permits our tests below to work reliably.
		* We only convert entities that are within tags since
		* these are the ones that will pose security problems.
		*
		*/
	results=str.match(/<.*?>/g, str)
	if(results) {
		
		var i
		for(i=0;i<results.length;i++) 
		{
			str = str.replace(results[i],html_entity_decode(results[i]));
		}
	}
	/*
		* Convert all tabs to spaces
		*
		* This prevents strings like this: ja    vascript
		* Note: we deal with spaces between characters later.
		*
		*/        
	str = str.replace(/\\t+/g, " ")
	
	/*
		* Makes PHP tags safe
		*
		*  Note: XML tags are inadvertently replaced too:
		*
		*    < ?xml
		*
		* But it doesn't seem to pose a problem.
		*
		*/          
	str = str.replace(/<\?php/g,'&lt;?php');
	str = str.replace(/<\?PHP/g,'&lt;?PHP');
	str = str.replace(/<\?/g,'&lt;?');
	str = str.replace(/\?>/g,'?&gt;');
	words = new Array('javascript', 'vbscript', 'script', 'applet', 'alert', 'document', 'write', 'cookie', 'window');
	for(t in words)
	{
		temp = '';
		for (i = 0; i < words[t].length; i++)
		{
			temp += words[t].substr( i, 1)+"\\s*";
		}
		
		temp = temp.substr( 0,temp.length-3);
		myRegExp = new RegExp(temp, "gi")
		str = str.replace(myRegExp, words[t]);
		//$str = preg_replace('#'.ucfirst($temp).'#s', ucfirst($word), $str);
	}
	
	/*
		* Remove disallowed Javascript in links or img tags
				*/
	str=str.replace(/\/<a.+?href=.*?(alert\(|alert&\#40;|javascript\:|window\.|document\.|\.cookie|<script|<xss).*?\>.*?<\/a>/gi,"")
	str = str.replace(/<img.+?src=.*?(alert\(|alert&\#40;|javascript\:|window\.|document\.|\.cookie|<script|<xss).*?\>/gi,"");
	str =str.replace(/<(script|xss).*?\>/gi,"")
	/*
		* Remove JavaScript Event Handlers
		*
		* Note: This code is a little blunt.  It removes
		* the event handler and anything up to the closing >, 
		* but it's unlkely to be a problem.
		*/
	str = str.replace(/(<[^>]+.*?)(onblur|onchange|onclick|onfocus|onload|onmouseover|onmouseup|onmousedown|onselect|onsubmit|onunload|onkeypress|onkeydown|onkeyup|onresize)[^>]*>/gi,"$1");
	
	/*
		* Sanitize naughty HTML elements
		*
		* If a tag containing any of the words in the list 
		* below is found, the tag gets converted to entities.
		*
		* So this: <blink>
		* Becomes: &lt;blink&gt;
		*/
	str = str.replace(/<(\/*\s*)(alert|applet|basefont|base|behavior|bgsound|blink|body|embed|expression|form|frameset|frame|head|html|ilayer|iframe|input|layer|link|meta|object|plaintext|style|script|textarea|title|xml|xss)([^>]*)>/ig, "&lt;$1$2$3&gt;");
		
		/*
		* Sanitize naughty scripting elements
		*
		* Similar to above, only instead of looking for
		* tags it looks for PHP and JavaScript commands
		* that are disallowed.  Rather than removing the
		* code, it simply converts the parenthesis to entities
		* rendering the code unexecutable.
		*
		* For example:    eval('some code')
		* Becomes:        eval&#40;'some code'&#41;
		*/
	str = str.replace(/(alert|cmd|passthru|eval|exec|system|fopen|fsockopen|file|file_get_contents|readfile|unlink)(\s*)\((.*?)\)/gi, "$1$2&#40;$3&#41;");
	
	/*
		* Final clean up
		*
		* This adds a bit of extra precaution in case
		* something got through the above filters
		*/
	bad = new Array('document.cookie','document.write','window.location',"javascript\s*:","Redirect\s+302")
	
	
	for (val in bad)
	{
		myRegExp = new RegExp(bad[val], "gi")
		str = str.replace(myRegExp, bad[val]);   
	}
	
	str=str.replace(/<!--/g,"&lt;!--")
	str=str.replace(/-->/g,"--&gt;")
	
	
	
	return str
}

function html_entity_decode(str) {
var ta=document.createElement("textarea");
  ta.innerHTML=str.replace(/</g,"&lt;").replace(/>/g,"&gt;");
  result = ta.value;
  result = result.replace(/&#x([0-9a-f]{2,5})/g, String.fromCharCode("$1"));
  result= result.replace(/&#([0-9]{2,4})/g, String.fromCharCode("$1"));
  return result;
		
}